﻿using System.Drawing;
using System.Linq;
using BroodWar.Addon;
using BroodWar.Api;
using BroodWar.Terrain;

namespace BasicAIModule
{
	internal class EnhancedUi
	{
		public void Update()
		{
			DrawTerrain();
			DrawBases();
			DrawProgress();
		}

		private void DrawBases()
		{
			//we will iterate through all the base locations, and draw their outlines.
			foreach (var baseLocation in TerrainAnalyzer.BaseLocations)
			{
				var tile = baseLocation.TilePosition;
				var pos = baseLocation.Position;

				//draw outline of center location
				Game.DrawBoxMap(pos.X*32, pos.Y*32, pos.X*32 + 4*32, pos.Y*32 + 3*32, Color.Blue, false);

				//draw a circle at each mineral patch
				foreach (var p in baseLocation.Minerals.Select(mineral => mineral.Position))
				{
					Game.DrawCircleMap(p.X, p.Y, 30, Color.Cyan, false);
				}

				//draw the outlines of vespene geysers
				foreach (var p in baseLocation.Geysers.Select(geyser=>geyser.TilePosition))
				{
					Game.DrawBoxMap(p.X*32, p.Y*32, p.X*32 + 4*32, p.Y*32 + 2*32, Color.Orange, false);
				}

				//if this is an island expansion, draw a yellow circle around the base location
				if(!baseLocation.IsIsland)
					return;

				Game.DrawCircleMap(tile.X, tile.Y, 80, Color.Yellow, false);
			}
		}

		private void DrawTerrain()
		{
			//we will iterate through all the regions and draw the polygon outline of it in green.
			foreach (var polygon in TerrainAnalyzer.Regions.Select(region => region.Polygon))
			{
				for (var j = 0; j < polygon.Count; j++)
				{
					var point1 = polygon[j];
					var point2 = polygon[(j + 1)%polygon.Count];
					Game.DrawLineMap(point1.X, point1.Y, point2.X, point2.Y, Color.Green);
				}
			}

			//we will visualize the chokepoints with yellow lines
			foreach (var region in TerrainAnalyzer.Regions)
			{
				foreach (var chokepoint in region.Chokepoints)
				{
					var point1 = chokepoint.Sides.Item1;
					var point2 = chokepoint.Sides.Item2;
					Game.DrawLineMap(point1.X, point1.Y, point2.X, point2.Y, Color.Yellow);
				}
			}
		}

		private void DrawProgress()
		{
			var constructing = UnitGroupManager.SelectAll().Filter(FilterFlag.isBuilding).FilterNot(FilterFlag.isCompleted);
			foreach (var unit in constructing)
			{
				var progress = 1.0 - (double) unit.RemainingBuildTime/unit.UnitType.Price.TimeFrames;
				DrawProgressBar(unit.Position, progress, Color.Red);
			}

			var producing = UnitGroupManager.SelectAll().Filter(FilterFlag.isTraining);
			foreach (var unit in producing)
			{
				if (unit.RemainingTrainTime <= 0)
					continue;
				var progress = 1.0 - (double) unit.RemainingTrainTime/unit.TrainingQueue.First().Price.TimeFrames;
				DrawProgressBar(unit.Position, progress, Color.Green);
			}
		}

		private void DrawProgressBar(Position pos, double progressFaction, Color innerBar)
		{
			const int width = 20, height = 4;
			var outline = Color.Blue;
			var barBg = Color.FromArgb(0, 0, 170);
			int xLeft = pos.X - width / 2, xRight = pos.X + width / 2;
			int yTop = pos.Y - height / 2, yBottom = pos.Y + height / 2;

			//Draw outline
			Game.DrawLineMap(xLeft + 1, yTop, xRight - 1, yTop, outline);        //top
			Game.DrawLineMap(xLeft + 1, yBottom, xRight - 1, yBottom, outline);  //bottom
			Game.DrawLineMap(xLeft, yTop + 1, xLeft, yBottom, outline);          //left
			Game.DrawLineMap(xRight - 1, yTop + 1, xRight - 1, yBottom, outline);//right
			//Draw bar
			Game.DrawBoxMap(xLeft + 1, yTop + 1, xRight - 1, yBottom, barBg, true);
			//Draw progress bar
			var innerWidth = (xRight - 1) - (xLeft + 1);
			var progressWidth = (int) (progressFaction * innerWidth);
			Game.DrawBoxMap(xLeft + 1, yTop + 1, (xLeft + 1) + progressWidth, yBottom, innerBar, true);
		}
	}
}
